/*
 * CAudioEncoder.h
 *
 *  Created on: 2017年9月29日
 *      Author: terry
 */

#ifndef CAUDIOENCODER_H_
#define CAUDIOENCODER_H_

#include "AudioEncoder.h"
#include "MFormatUtil.h"
#include "AutoMFormat.h"
#include "Ffmpeg.h"
#include "AVFramePtr.h"
#include <string>
#include "TByteBuffer.h"


extern "C"
{
    #include "libswresample/swresample.h"
    #include "libavutil/audio_fifo.h"
}


class CAudioEncoder: public AudioEncoder
{
public:
	CAudioEncoder();
	virtual ~CAudioEncoder();

	virtual int open(int channels, int rate, int codec, int bitrate);

	virtual void close();

	virtual bool isOpen();

	virtual int encode(uint8_t* data, int size, int64_t pts, MPacket* pkt);

	virtual void flush();

	virtual MFormat& getFormat();

	virtual bool setParam(int param, int value);

	void setAdts(bool isAdts);

protected:
	int openEncoder();
	void closeEncoder();
	bool isEncoderOpen();

	bool isSamleFormat(int fmt, int channels, int sampleRate);

	bool getAudioConfig(std::string& config);

	int resample(AVFrame* inFrame, AVFrame* outFrame);


	void storeFrame(AVFrame* frame);
	bool loadFrame(AVFrame* frame, int nb_samples);
	void closeFifo();
	int getFifoSize();

	bool encodeFrame(AVFrame* frame, AVPacket* pkt);

	bool encodeFrame(AVPacket* pkt);
	bool encodeFrame(MPacket* pkt);

	void makePacket(AVPacket& avpkt, MPacket* pkt);

protected:
	AutoMFormat		m_format;
	AVCodecContext* m_context;
	SwrContext*		m_swrContext;
	AVAudioFifo*	m_fifo;
	int64_t         m_sampleCount;
	std::string     m_extradata;

	comn::ByteBuffer	m_buffer;
	bool	m_isAdts;
	int		m_frameSize;

};

#endif /* CAUDIOENCODER_H_ */
